home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
parallel
/
lindasrc
< prev
next >
Wrap
Text File
|
1992-04-11
|
24KB
|
611 lines
/*===================================================================*/
/*----Linda Arity Prolog Tuple Server and Client Libraries */
/*---- */
/*----Written by Geoff Sutcliffe, August 1990 */
/*===================================================================*/
/*----Server library */
/*===================================================================*/
/*----Start the server, with a goal and its Prolog file */
server_go(Server_machine,Client_machine_definitions,
Communication_information):-
assertz(server_machine__(Server_machine)),
convert_machine_definitions_to_names__(Client_machine_definitions,
Client_machines),
set_up_server_communications__(Server_machine,Client_machines,
Communication_information),
!,
initialise_client_machines__(Client_machines),
control_service__,
terminate_client_machines__(Client_machines),
close_down_server_communications__(Server_machine,Client_machines,
Communication_information),
retract_once__(server_machine__(Server_machine)).
server_go(_,_):-
write('Error : Communications not set up'),
nl.
/*-------------------------------------------------------------------*/
convert_machine_definition_to_names__(Machine_definition,[]):-
Machine_definition =.. [_,Index],
Index < 1,
!.
convert_machine_definition_to_names__(Machine_definition,
[Machine_definition]):-
Machine_definition =.. [_,1],
!.
convert_machine_definition_to_names__(Machine_definition,
[Machine_definition|Rest_of_names]):-
Machine_definition =.. [Actual_name,Index],
Next_index is Index - 1,
Next_machine_definition =.. [Actual_name,Next_index],
convert_machine_definition_to_names__(Next_machine_definition,
Rest_of_names).
/*-------------------------------------------------------------------*/
/*----Convert names like bison(3) into bison(0),bison(1),bison(2) */
convert_machine_definitions_to_names__([],[]).
convert_machine_definitions_to_names__([First_machine_definition|
Rest_of_machine_definitions],Client_machine_names):-
convert_machine_definition_to_names__(First_machine_definition,
First_names),
convert_machine_definitions_to_names__(Rest_of_machine_definitions,
Rest_of_names),
append__(First_names,Rest_of_names,Client_machine_names).
/*-------------------------------------------------------------------*/
/*----Get a list of all available machines, in use and not in use */
get_machines_lists__(Machines_in_use,Machines_not_in_use):-
findall(Machine_in_use,machine__(Machine_in_use,in_use),
Machines_in_use),
findall(Machine_not_in_use,machine__(Machine_not_in_use,
not_in_use),Machines_not_in_use).
/*-------------------------------------------------------------------*/
/*----Repeatedly allow the user to specify a goal and file */
control_service__:-
write('Options : "start" client; "exit" : '),
read(Option),
Option.
/*-------------------------------------------------------------------*/
/*----Do the option chosen by the user in service control */
start:-
get_machines_lists__(Machines_in_use,Machines_not_in_use),
write('In use : '),
write(Machines_in_use),
nl,
write('Free : '),
write(Machines_not_in_use),
nl,
write('Client : '),
read(Client),
write('Goal : '),
read(Goal),
write('Files : '),
read(Files),
server_machine__(Server_machine),
server_eval__(Server_machine,Client,Goal,Files),
serve__,
control_service__.
exit.
/*-------------------------------------------------------------------*/
/*----If no machines in use the serving is over */
serve__:-
repeat,
receive_term_from_any_client__(Request),
do_request__(Request),
not(machine__(_,in_use)).
/*-------------------------------------------------------------------*/
/*----Do a client request by simply evaluating it */
do_request__(Request):-
Request,
!.
/*----If a request fails, then output */
do_request__(Request):-
write('Error : '),
write(Request),
write(' : failed'),
nl.
/*-------------------------------------------------------------------*/
/*----Start up the client machines by noting their availability */
initialise_client_machines__([]).
initialise_client_machines__([First_client|Rest_of_clients]):-
power_up_machine__(First_client),
assertz(machine__(First_client,not_in_use)),
initialise_client_machines__(Rest_of_clients).
/*-------------------------------------------------------------------*/
/*----Stop client machine by sending them a message to say it's all */
/*----over, and denoting their availability */
terminate_client_machines__([]).
terminate_client_machines__([First_client_machine|
Rest_of_client_machines]):-
debug_write__('Close : '),
debug_write__(First_client_machine),
debug_nl__,
power_down_machine__(First_client_machine),
retract_once__(machine__(First_client_machine,not_in_use)),
terminate_client_machines__(Rest_of_client_machines).
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*----Procedures for doing eval requests
/*===================================================================*/
/*----Start a new query in a Prolog file */
server_eval__(Originating_machine,Machine,Goal,Files):-
retract_once__(machine__(Machine,not_in_use)),
!,
start_client__(Machine),
assertz(machine__(Machine,in_use)),
send_term_to_client__(Machine,client_eval__(Machine,Goal,
Files)),
debug_write__('Client : '),
debug_write__(Originating_machine),
debug_write__(' : starts : '),
debug_write__(Machine),
debug_write__(' : '),
debug_write__(Goal),
debug_write__(' : '),
debug_write__(Files),
debug_nl__.
server_eval__(Originating_machine,Machine,Goal,Files):-
check_machine_is_in_use__(Machine),
!,
note_waiting__(server_eval__(Originating_machine,Machine,Goal,
Files)),
debug_write__('Wait : '),
debug_write__(Machine),
debug_write__(' : '),
debug_write__(Goal),
debug_write__(' : '),
debug_write__(Files),
debug_nl__.
server_eval__(Originating_machine,Machine,Goal,Files):-
write('Error : eval for non-existant machine : '),
write(Machine),
nl.
/*-------------------------------------------------------------------*/
/*----Check that a requested machine does exist, taking into account */
/*----under specified machine names. */
check_machine_is_in_use__(Machine):-
var(Machine),
!,
machine__(_,in_use).
check_machine_is_in_use__(Machine):-
Machine =.. [Name,Index],
var(Index),
!,
Machine_to_check =.. [Name,_],
machine__(Machine_to_check,in_use).
check_machine_is_in_use__(Machine):-
machine__(Machine,in_use).
/*-------------------------------------------------------------------*/
/*----Start a new query in a Prolog file, if possible. Return info */
server_evalp__(Originating_machine,Machine,Goal,Files):-
retract_once__(machine__(Machine,not_in_use)),
!,
assertz(machine__(Machine,in_use)),
start_client__(Machine),
send_term_to_client__(Machine,client_eval__(Machine,Goal,
Files)),
send_term_to_client__(Originating_machine,Machine),
debug_write__('Client : '),
debug_write__(Originating_machine),
debug_write__(' : starts : '),
debug_write__(Machine),
debug_write__(' : '),
debug_write__(Goal),
debug_write__(' : '),
debug_write__(Files),
debug_nl__.
server_evalp__(Originating_machine,Machine,Goal,Files):-
send_term_to_client__(Originating_machine,fail),
debug_write__('Fail : '),
debug_write__(Machine),
debug_write__(' : '),
debug_write__(Goal),
debug_write__(' : '),
debug_write__(Files),
debug_nl__.
/*-------------------------------------------------------------------*/
/*----This is executed by the server when the client has completed an*/
/*----eval */
end_eval__(Machine):-
debug_write__('End : '),
debug_write__(Machine),
debug_nl__,
retract_once__(machine__(Machine,in_use)),
stop_client__(Machine),
assertz(machine__(Machine,not_in_use)),
redo_waiting_requests__(machine__(Machine,not_in_use)).
/*===================================================================*/
/*----Procedures for out requests */
/*===================================================================*/
/*----Execute out, checking for any ins and rds waiting for the tuple*/
server_out__(Machine,Tuple):-
do_server_out__(Machine,Tuple),
redo_waiting_requests__(Tuple).
/*-------------------------------------------------------------------*/
/*----This actually puts the tuple in tuple space */
do_server_out__(Machine,Tuple):-
assertz(Tuple),
debug_write__('Added : '),
debug_write__(Tuple),
debug_write__(' : from : '),
debug_write__(Machine),
debug_nl__.
/*===================================================================*/
/*----Procedures for in requests */
/*===================================================================*/
/*----Execute in, if not possible then put on waiting queue */
server_in__(Machine,Tuple):-
do_server_in__(Machine,Tuple),
!,
send_term_to_client__(Machine,Tuple).
server_in__(Machine,Tuple):-
debug_write__('in wait : '),
debug_write__(Tuple),
debug_write__(' : for : '),
debug_write__(Machine),
debug_nl__,
note_waiting__(server_in__(Machine,Tuple)).
/*-------------------------------------------------------------------*/
/*----Execute inp, if not possible return fail */
server_inp__(Machine,Tuple):-
do_server_in__(Machine,Tuple),
!,
send_term_to_client__(Machine,Tuple).
server_inp__(Machine,Tuple):-
send_term_to_client__(Machine,fail),
debug_write__('No inp : '),
debug_write__(Tuple),
debug_write__(' : for : '),
debug_write__(Machine),
debug_nl__.
/*-------------------------------------------------------------------*/
/*----This actually gets the tuple out of tuple space */
do_server_in__(Machine,Tuple):-
retract_once__(Tuple),
debug_write__('Removed : '),
debug_write__(Tuple),
debug_write__(' : to : '),
debug_write__(Machine),
debug_nl__.
/*===================================================================*/
/*----Procedures for rd requests */
/*===================================================================*/
/*----Execute rd if not possible then put on waiting queue */
server_rd__(Machine,Tuple):-
do_server_rd__(Machine,Tuple),
!,
send_term_to_client__(Machine,Tuple).
server_rd__(Machine,Tuple):-
debug_write__('rd wait : '),
debug_write__(Tuple),
debug_write__(' : for : '),
debug_write__(Machine),
debug_nl__,
note_waiting__(server_rd__(Machine,Tuple)).
/*-------------------------------------------------------------------*/
/*----Execute rdp, if not possible return fail */
server_rdp__(Machine,Tuple):-
do_server_rd__(Machine,Tuple),
!,
send_term_to_client__(Machine,Tuple).
server_rdp__(Machine,Tuple):-
send_term_to_client__(Machine,fail),
debug_write__('No rdp : '),
debug_write__(Tuple),
debug_write__(' : for : '),
debug_write__(Machine),
debug_nl__.
/*-------------------------------------------------------------------*/
/*----Execute rdall, returning the collected tuples */
server_rdall__(Machine,Tuple,Maximum_replies):-
findallmax__(Tuple,Tuple,Reply_tuples,Maximum_replies),
send_term_to_client__(Machine,Reply_tuples).
/*-------------------------------------------------------------------*/
/*----This actually checks for the tuple in tuple space */
do_server_rd__(Machine,Tuple):-
Tuple,
debug_write__('Examine : '),
debug_write__(Tuple),
debug_write__(' : for : '),
debug_write__(Machine),
debug_nl__.
/*-------------------------------------------------------------------*/
/*----muProlog fix for tuples that aren't defined */
traperror(enoproc,_,fail).
/*===================================================================*/
/*----Procedures for the waiting queue */
/*===================================================================*/
/*-------------------------------------------------------------------*/
/*----Initial waiting list is empty */
waiting_list__([]).
/*-------------------------------------------------------------------*/
note_waiting__(Request):-
retract(waiting_list__(List)),
assertz(waiting_list__([Request|List])).
/*-------------------------------------------------------------------*/
redo_waiting_requests__(Outed_tuple):-
retract(waiting_list__(Waiting_requests)),
assertz(waiting_list__([])),
doall__(Waiting_requests).
/*-------------------------------------------------------------------*/
doall__([]):-
!.
doall__([First|Rest]):-
First,
doall__(Rest).
/*===================================================================*/
/*----Remote i/o procedures */
/*===================================================================*/
server_remote_write__(Machine,Term):-
write(Machine),
write(' : '),
write(Term),
nl.
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*----Client library */
/*===================================================================*/
/*----This is for networks that have to have the client machines */
/*----started manually. */
client_go(Server_machine,Client_machine,Communication_information):-
set_up_client_communications__(Server_machine,Client_machine,
Communication_information),
!,
client_machine_loop__,
close_down_client_communications__(Server_machine,Client_machine,
Communication_information).
client_go(_,_):-
write('Error : Communications not set up'),
nl.
/*-------------------------------------------------------------------*/
/*----A manually started machine sits and waits for client_eval__ and*/
/*----exit__ mesages */
client_machine_loop__:-
repeat,
receive_term_from_server__(Reply),
Reply,
Reply == exit__.
/*-------------------------------------------------------------------*/
consult_each_file__([]):-
!.
consult_each_file__([First_file|Rest_of_files]):-
name(First_file,File_list),
append__("linda/",File_list,Full_list),
name(Full_file_path,Full_list),
consult(Full_file_path),
consult_each_file__(Rest_of_files).
/*-------------------------------------------------------------------*/
/*----This is used to start up a new job on this client. */
client_eval__(This_machine_name,Goal,Files):-
assertz(client_machine__(This_machine_name)),
consult_each_file__(Files),
Goal,
!,
send_request__(end_eval__),
retract(client_machine__(This_machine_name)).
client_eval__(_,_,_):-
send_request__(end_eval__),
retract(client_machine__(This_machine_name)).
/*-------------------------------------------------------------------*/
/*----This is used to close down manually started client machines */
exit__.
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*---Procedures for doing Linda operations */
/*===================================================================*/
/*----eval sends a request */
eval(Machine,Goal,Files):-
send_request__(server_eval__(Machine,Goal,Files)).
/*-------------------------------------------------------------------*/
/*----evalp sends a request */
evalp(Machine,Goal,Files):-
send_request__(server_evalp__(Machine,Goal,Files)),
receive_term_from_server__(Machine).
/*-------------------------------------------------------------------*/
/*----out sends a request */
out(Tuple):-
send_request__(server_out__(Tuple)).
/*-------------------------------------------------------------------*/
/*----in sends a request and reads the reply */
in(Tuple):-
send_request__(server_in__(Tuple)),
receive_term_from_server__(Tuple).
/*-------------------------------------------------------------------*/
/*----inp sends a request and reads the reply. The reply may be fail */
inp(Tuple):-
send_request__(server_inp__(Tuple)),
receive_term_from_server__(Tuple).
/*-------------------------------------------------------------------*/
/*----rd sends a request and reads the reply */
rd(Tuple):-
send_request__(server_rd__(Tuple)),
receive_term_from_server__(Tuple).
/*-------------------------------------------------------------------*/
/*----rdp sends a request and reads the reply. The reply may be fail */
rdp(Tuple):-
send_request__(server_rdp__(Tuple)),
receive_term_from_server__(Tuple).
/*-------------------------------------------------------------------*/
/*----rdall sends a request for all tuples. Reply is a list */
rdall(Tuple,Maximum_replies,Reply_tuples):-
send_request__(server_rdall__(Tuple,Maximum_replies)),
receive_term_from_server__(Reply_tuples).
/*-------------------------------------------------------------------*/
/*----remote_write asks the server to do output */
remote_write(Term):-
send_request__(server_remote_write__(Term)).
/*-------------------------------------------------------------------*/
/*----Requests sent from a client to the server */
send_request__(Request):-
/*----Stuff this machine's name and index on the front */
Request =.. [Principle|Arguments],
member__(Principle,[server_rd__,server_rdp__,server_in__,
server_inp__,server_eval__,server_evalp__,end_eval__,server_out__,
server_remote_write__]),
!,
client_machine__(Machine),
Message =.. [Principle,Machine|Arguments],
send_term_to_server__(Message).
send_request__(Request):-
send_term_to_server__(Request).
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*----Debugging tools */
/*===================================================================*/
debug_write__(Term):-
debugging__,
!,
write(Term).
debug_write__(_).
/*-------------------------------------------------------------------*/
debug_nl__:-
debugging__,
!,
nl.
debug_nl__.
/*-------------------------------------------------------------------*/
debugging__:-
fail.
/*===================================================================*/
/*----Utilities */
/*===================================================================*/
/*-------------------------------------------------------------------*/
retract_once__(Term):-
retract(Term),
!.
/*-------------------------------------------------------------------*/
append__([],List,List).
append__([Head|Tail],List,[Head|New_list]):-
append__(Tail,List,New_list).
/*-------------------------------------------------------------------*/
member__(Element,[Element|_]):-
!.
member__(Element,[_|Tail]):-
member__(Element,Tail).
/*-------------------------------------------------------------------*/
/*----Quick and dirty findall implementation */
findall(Variable,Goal,_):-
Goal,
assertz(findall_result__(Variable)),
fail.
findall(_,_,List):-
collectall__(List).
collectall__([First|Rest]):-
retract(findall_result__(First)),
!,
collectall__(Rest).
collectall__([]).
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*----muProlog specific stuff */
/*===================================================================*/
/*----Start up for muProlog clients. The interpreter starts after the*/
/*----save point. The communicator will exec the saved file, thus if */
/*----any changes are made to this file, linda_go must be re-run to */
/*----create a new version of the linda file. */
make_linda:-
save(linda),
receive_term_from_server__(client_eval__(Machine,Goal,Files)),
client_eval__(Machine,Goal,Files),
exit(0).
/*-------------------------------------------------------------------*/
make_new_server_entries(_,1,Entries,Entries):-
!.
make_new_server_entries(Server_machine_name,Count,
Rest_of_entries,[First_entry|Rest_of_entries]):-
New_count is Count - 1,
First_entry =.. [Server_machine_name,New_count].
/*-------------------------------------------------------------------*/
update_server_entry([First_entry|Rest_of_entries],Server_machine_name,
New_server_entries):-
First_entry =.. [Server_machine_name,Count],
!,
make_new_server_entries(Server_machine_name,Count,
Rest_of_entries,New_server_entries).
update_server_entry([First_entry|Rest_of_entries],Server_machine_name,
[First_entry|New_rest_of_entries]):-
update_server_entry(Rest_of_entries,Server_machine_name,
New_rest_of_entries).
/*-------------------------------------------------------------------*/
make_mugo(Server_machine_name):-
retract(client_list(Machine_list)),
update_server_entry(Machine_list,Server_machine_name,
New_machine_list),
asserta(client_list(New_machine_list)),
save(mugo),
client_list(Client_list),
server_go(server(1),Client_list,null).
/*-------------------------------------------------------------------*/
client_list(
[bettong(1),bilby(1),bison(1),budgie(1),cricket(1),
dunnart(1),hawk(1),kowari(1),melomys(1),narbelek(1),ningaui(1),
numbat(1),planigale(1),potoroo(1),quenda(1),quokka(1),quoll(1),
tammar(1),wambenger(1),warabi(1),woylie(1)]).
/*-------------------------------------------------------------------*/
/*===================================================================*/
/*----Problem specific stuff */
/*===================================================================*/
genetic1(Number_of_transferers,Number_of_breeders,Pool_size,
Breeds,File_name):-
/* asserta(debugging__), */
/* asserta(debugging_net__), */
server_machine__(Server_machine),
client_list([First_client|Rest_of_client_list]),
first_N(Number_of_transferers,Transferers,Rest_of_client_list,
Other_clients),
first_N(Number_of_breeders,Breeders,Other_clients,_),
server_eval__(Server_machine,First_client,
start_breeding(Transferers,Breeders,Pool_size,Breeds,File_name),
[genetic1,File_name]),
serve__,
control_service__.
/*-------------------------------------------------------------------*/
first_N(0,[],Left,Left):-
!.
first_N(N,[First|Rest],[First|Available],Left):-
N1 is N - 1,
first_N(N1,Rest,Available,Left).
/*-------------------------------------------------------------------*/
genetic2(Number_of_breeders,Pool_size,Breeds,Youth_advantage,
File_name):-
/* asserta(debugging__), */
/* asserta(debugging_net__), */
server_machine__(Server_machine),
client_list([First_client|Rest_of_client_list]),
first_N(Number_of_breeders,Breeders,Rest_of_client_list,_),
server_eval__(Server_machine,First_client,
start_breeding(Breeders,Pool_size,Breeds,Youth_advantage,File_name),
[genetic2,File_name]),
serve__,
control_service__.
/*-------------------------------------------------------------------*/